package ocio.actions;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import ocio.beans.Admin;
import ocio.beans.Cliente;
import ocio.beans.Producto;
import ocio.beans.Proveedor;
import ocio.beans.Subscripcion;
import ocio.beans.Usuario;
import ocio.services.AdminService;
import ocio.services.ClienteService;
import ocio.services.ProveedorService;
import ocio.services.ProductoService;
import ocio.services.ServiceLocator;
import ocio.services.UsuarioService;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * Clase destinataria de petición de acceso como usuario registrado.
 * @author Esther García Galán
 * @author Rubén Gómez Vales
 * @version 1.0 13/05/2014
 * @see ocio.beans.Usuario
 */
public class LoginAction extends ActionSupport{

	private static final long serialVersionUID = -2779360820801900258L;
	private String correo;
	private String password;
	private Boolean baja;
	private String mensaje="";
	
	private Set<Subscripcion> listaSubcripciones= new HashSet<Subscripcion>();
	private List<Producto> listaProductos = new ArrayList<Producto>();
	private Admin admin;
	private Cliente cliente;

    /**
	 * Método execute() de la clase ActionSupport de Struts 2. 
	 * Solicita los servicios para comprobar si el usuario y contraseña introducidos
	 * se encuentran en la base de datos, introduce datos del mismo en la sesión y en caso de 
	 * tratarse de un usuario con subscripciones busca los productos cuyas características 
	 * coinciden con los filtros establecidos en las mismas.
	 * @return un string que indica la respuesta de la acción ejecutada sobre la petición del usuario.
	 */
	public String execute(){

		String resultado="fail";
		
		ServiceLocator serviceLocator = ServiceLocator.getServiceLocator();		

		UsuarioService usuarioService = (UsuarioService)serviceLocator.getService("Usuario");		
		
		this.baja=false; //Solo se pueden logear los usuarios no dados de baja
		List<Object> result = usuarioService.searchByFields(this);
						
		if (result.size()==0) {    				// Usuario no existente en base de datos			
			setMensaje("No se encuentra el usuario y/o contraseña");
			return "fail";
		} else {
			Usuario usuario = (Usuario)result.get(0);
			
			Map<String,Object> sesion = ActionContext.getContext().getSession();
			sesion.put("MAIL", usuario.getCorreo());
			resultado = "success";
			switch (usuario.getRol()) {
            	case 1: 
            		sesion.put("ROL","Admin");
            		AdminService adminService = (AdminService)serviceLocator.getService("Admin");		
            		admin = (Admin)adminService.searchById(usuario.getId());
            		
            		if (admin.getSubscripciones().size()>0) { 
            			//Recuperamos lista de subscripciones del usuario...
            			this.listaSubcripciones = admin.getSubscripciones();
            			resultado="alertas";
            		}
            		
            		//Inicialmente admin tiene funciones de cliente y proveedor por defecto,para poder
            		//dar altas de productos y subscripciones. A medida que consulte datos de otro
            		//proveedor o cliente, se le desabilitarán los botones para que no pueda suplantar
            		//la identidad de los demás. Esto es, puede dar de alta solo en su cuenta.
            		sesion.put("USUARIO", admin.getId());
            		sesion.put("IDPROVEEDOR",admin.getId());
            		sesion.put("IDCLIENTE",admin.getId());
                    break;
            	case 2: 
            		sesion.put("ROL","Cliente");
            		ClienteService clienteService = (ClienteService)serviceLocator.getService("Cliente");		
            		cliente = (Cliente)clienteService.searchById(usuario.getId()); 
            		
            		if (cliente.getSubscripciones().size()>0) { 
            			//Recuperamos lista de subscripciones del usuario...
            			this.listaSubcripciones = cliente.getSubscripciones();
            			resultado="alertas";
            		}
            		
            		sesion.put("USUARIO", cliente.getId());
            		sesion.put("IDCLIENTE",cliente.getId());

                    break;
            	case 3:  
            		sesion.put("ROL","Proveedor");
            		ProveedorService proveedorService = (ProveedorService)serviceLocator.getService("Proveedor");		
            		Proveedor proveedor = (Proveedor)proveedorService.searchById(usuario.getId());
            		sesion.put("USUARIO", proveedor.getId());
            		sesion.put("IDPROVEEDOR",proveedor.getId());
            		sesion.put("TIPOPROVEEDOR", proveedor.getTipo());
            		break;
			}
			
			if (this.listaSubcripciones.size()>0) {
				//La recorremos usando los criterios para recuperar productos que los cumplan...
				ProductoService prodS = (ProductoService)serviceLocator.getService("Producto");
				Iterator<Subscripcion> itr =this.listaSubcripciones.iterator();
				while (itr.hasNext()){
					Subscripcion s = itr.next();
					Producto p = new Producto();
					p.setSubtipo(s.getSubtipo());
					p.setProvincia(s.getProvincia());
				
					//productos que cumplen una de las subscripciones, añadir al SET
					Iterator<Object> itrLPaux = prodS.searchByFields(p).iterator();
					while (itrLPaux.hasNext()){
						Producto pro = (Producto)itrLPaux.next();
						this.listaProductos.add(pro);
					}	
				}
			}	
			
		}
		return resultado;  
	}
	
	public String getCorreo() {
		return correo;
	}
	public void setCorreo(String correo) {
		this.correo = correo;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	public Boolean getBaja() {
		return baja;
	}

	public void setBaja(Boolean baja) {
		this.baja = baja;
	}

	public String getMensaje() {
		return mensaje;
	}

	public void setMensaje(String mensaje) {
		this.mensaje = mensaje;
	}

	public Set<Subscripcion> getListaSubcripciones() {
		return listaSubcripciones;
	}

	public void setListaSubcripciones(Set<Subscripcion> listaSubcripciones) {
		this.listaSubcripciones = listaSubcripciones;
	}

	public List<Producto> getListaProductos() {
		return listaProductos;
	}

	public void setListaProductos(List<Producto> listaProductos) {
		this.listaProductos = listaProductos;
	}

	public Admin getAdmin() {
		return admin;
	}

	public void setAdmin(Admin admin) {
		this.admin = admin;
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}
	
	
}
